package com.mcp.converter.domain.rule.compatibility.function;

import com.mcp.converter.domain.checker.IncompatibilityDetail;
import com.mcp.converter.shared.response.sql.SQLElement;
import com.mcp.converter.domain.rule.compatibility.AbstractFunctionRule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.Set;

/**
 * LISTAGG函数兼容性规则
 * OceanBase中LISTAGG函数的参数和语法与Oracle有差异
 * @author zengxiong
 */
public class ListaggFunctionRule extends AbstractFunctionRule {

    private static final Logger logger = LoggerFactory.getLogger(ListaggFunctionRule.class);
    private static final String RULE_ID = "FN006";
    private static final String RULE_NAME = "LISTAGG函数语法差异";
    private static final String RULE_DESCRIPTION = "OceanBase中LISTAGG函数的参数和语法与Oracle存在差异";

    public ListaggFunctionRule() {
        super(RULE_ID, RULE_NAME, RULE_DESCRIPTION);
        setIncompatibilityDetail(
            "OceanBase 4.2.1中LISTAGG函数与Oracle的兼容性限制：\n" +
            "1. 仅支持基础LISTAGG语法：LISTAGG(expr, delimiter) WITHIN GROUP (ORDER BY)\n" +
            "2. 不支持Oracle 12c R2+的高级特性：\n" +
            "   - ON OVERFLOW TRUNCATE子句\n" +
            "   - WITH COUNT选项\n" +
            "   - DISTINCT关键字\n" +
            "3. 最大返回字符串长度限制可能与Oracle不同",
            
            "使用不支持的语法将导致：\n" +
            "1. SQL解析失败\n" +
            "2. 执行时报错\n" +
            "3. 预期外的截断行为",
            
            "建议：\n" +
            "1. 仅使用基础LISTAGG语法\n" +
            "2. 手动处理字符串截断\n" +
            "3. 对于大数据量，考虑分批次处理\n" +
            "4. 监控结果长度避免溢出",
            
            IncompatibilityDetail.Severity.LOW
        );
    }

    @Override
    public boolean matches(Object target) {
        if (target == null) {
            logger.debug("Target is null");
            return false;
        }

        if (!(target instanceof SQLElement)) {
            logger.debug("Target is not SQLElement: {}", target.getClass().getName());
            return false;
        }

        SQLElement element = (SQLElement) target;
        
        // 检查是否为函数元素
        if (!isFunctionElement(element)) {
            logger.debug("Element is not a function: {}", element.getType());
            return false;
        }

        // 获取函数名并转换为大写
        String functionName = element.getName();
        if (functionName == null) {
            logger.debug("Function name is null");
            return false;
        }
        
        functionName = functionName.toUpperCase();
        
        // 检查是否为LISTAGG函数
        boolean isListagg = "LISTAGG".equals(functionName);
        
        if (isListagg) {
            String sql = element.getValue().toUpperCase();
            // 检测不支持的语法
            if (sql.contains("ON OVERFLOW") || sql.contains("WITH COUNT") || sql.contains("DISTINCT")) {
                logger.warn("检测到不支持的LISTAGG高级语法: {}", element.getValue());
                return false;
            }
            logger.debug("Found LISTAGG function: {}", element.getValue());
            return true;
        }

        logger.debug("Not a LISTAGG function: {}", functionName);
        return false;
    }
    
    @Override
    public Set<String> getIncompatibleFunctions() {
        // LISTAGG基础语法在OceanBase中是支持的，只是高级语法不支持
        return Collections.emptySet();
    }
}
